/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.formmetadata.replication;

import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataPackageHeader;
import com.inspur.edp.lcm.metadata.api.entity.MetadataProject;
import com.inspur.edp.lcm.metadata.api.entity.ProjectHeader;
import com.inspur.edp.lcm.metadata.api.mvnEntity.MavenPackageRefs;
import com.inspur.edp.web.common.customexception.WebCustomException;
import com.inspur.edp.web.common.io.FileUtility;
import com.inspur.edp.web.common.metadata.MetadataUtility;
import com.inspur.edp.web.common.serialize.SerializeUtility;
import com.inspur.edp.web.common.utility.StringUtility;
import com.inspur.edp.web.formmetadata.constant.I18nExceptionConstant;
import com.inspur.edp.web.formmetadata.constant.ReplicationConstant;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * description:
 *
 * @author Noah Guo
 * @date 2021/02/26
 */
public class ProjectInformationManager {
    public static void updateTargetProjectInformation(String[] sourceMetadataSegmentPathCollection, String sourceProjectName, String targetProjectName) {
        MetadataProject soureMetadataProject = getSourceProjectInformation(sourceMetadataSegmentPathCollection, sourceProjectName);

        MetadataProject targetMetadataProject = getTargetProjectInformation(sourceMetadataSegmentPathCollection, targetProjectName);

        synchroizeProjectInformation(soureMetadataProject, targetMetadataProject);

        // 保存目标工程配置文件
        String targetMetadataProjectStr = SerializeUtility.getInstance().serialize(targetMetadataProject, false);
        String targetProjectAbsolutePath = getTargetProjectAbsolutPath(sourceMetadataSegmentPathCollection, targetProjectName);
        FileUtility.writeFile(targetProjectAbsolutePath, targetProjectName + "." + ReplicationConstant.METADATA_PROJECT_FILE_SUFFIX, targetMetadataProjectStr);
    }

    private static MetadataProject getTargetProjectInformation(String[] soureMetadataSegmentPathColleciton, String targetProjectName) {
        String targetProjectAbsolutPath = getTargetProjectAbsolutPath(soureMetadataSegmentPathColleciton, targetProjectName);

        return getProjectInformation(targetProjectAbsolutPath, targetProjectName);
    }

    private static void synchroizeProjectInformation(MetadataProject soureMetadataProject, MetadataProject targetMetadataProject) {
        // 同步 MetadataPackageRefs
        if (soureMetadataProject.getMetadataPackageRefs() != null) {
            for (int i = 0; i < soureMetadataProject.getMetadataPackageRefs().size(); i++) {
                MetadataPackageHeader metadataPackageHeader = soureMetadataProject.getMetadataPackageRefs().get(i);
                boolean existsSameMetadataPackageHeader = false;
                if (targetMetadataProject.getMetadataPackageRefs() == null) {
                    targetMetadataProject.setMetadataPackageRefs(new ArrayList<>());
                }
                for (int j = 0; j < targetMetadataProject.getMetadataPackageRefs().size(); j++) {
                    if (Objects.equals(targetMetadataProject.getMetadataPackageRefs().get(j).getName(), soureMetadataProject.getMetadataPackageRefs().get(i).getName())) {
                        existsSameMetadataPackageHeader = true;
                        break;
                    }
                }

                if (!existsSameMetadataPackageHeader) {
                    targetMetadataProject.getMetadataPackageRefs().add(soureMetadataProject.getMetadataPackageRefs().get(i));
                }
            }
        }

        // 同步 ProjectRefs
        if (soureMetadataProject.getProjectRefs() != null) {
            for (int i = 0; i < soureMetadataProject.getProjectRefs().size(); i++) {
                ProjectHeader projectPackageHeader = soureMetadataProject.getProjectRefs().get(i);
                boolean existsSameProjectPackageHeader = false;
                if (targetMetadataProject.getProjectRefs() == null) {
                    targetMetadataProject.setProjectRefs(new ArrayList<>());
                }
                for (int j = 0; j < targetMetadataProject.getProjectRefs().size(); j++) {
                    if (Objects.equals(targetMetadataProject.getProjectRefs().get(j).getName(), soureMetadataProject.getProjectRefs().get(i).getName())) {
                        existsSameProjectPackageHeader = true;
                        break;
                    }
                }

                if (!existsSameProjectPackageHeader) {
                    targetMetadataProject.getProjectRefs().add(soureMetadataProject.getProjectRefs().get(i));
                }
            }
        }

        // 同步 MavenPackageRefs
        if (soureMetadataProject.getMavenPackageRefs() != null) {
            for (int i = 0; i < soureMetadataProject.getMavenPackageRefs().size(); i++) {
                MavenPackageRefs mavenHeader = soureMetadataProject.getMavenPackageRefs().get(i);
                boolean existsSameMavenHeader = false;
                if (targetMetadataProject.getMavenPackageRefs() == null) {
                    targetMetadataProject.setMavenPackageRefs(new ArrayList<>());
                }
                for (int j = 0; j < targetMetadataProject.getMavenPackageRefs().size(); j++) {
                    if (Objects.equals(targetMetadataProject.getMavenPackageRefs().get(j).getGroupId(), soureMetadataProject.getMavenPackageRefs().get(i).getGroupId())
                            && Objects.equals(targetMetadataProject.getMavenPackageRefs().get(j).getArtifactId(), soureMetadataProject.getMavenPackageRefs().get(i).getArtifactId())) {
                        existsSameMavenHeader = true;
                        break;
                    }
                }

                if (!existsSameMavenHeader) {
                    targetMetadataProject.getMavenPackageRefs().add(soureMetadataProject.getMavenPackageRefs().get(i));
                }
            }
        }
    }


    private static String getTargetProjectAbsolutPath(String[] soureMetadataSegmentPathColleciton, String targetProjectName) {
        StringBuilder targetProjectRelativePath = new StringBuilder();
        for (int i = 0; i <= 4; i++) {
            if (i != 0) {
                targetProjectRelativePath.append("/");
            }

            if (i == 3) {
                // 替换工程名
                targetProjectRelativePath.append(targetProjectName);
            } else {
                targetProjectRelativePath.append(soureMetadataSegmentPathColleciton[i]);
            }
        }

        return MetadataUtility.getInstance().getAbsolutePath(targetProjectRelativePath.toString());
    }


    public static MetadataProject getSourceProjectInformation(String[] soureMetadataSegmentPathColleciton, String sourceProjectName) {
        if (soureMetadataSegmentPathColleciton == null || soureMetadataSegmentPathColleciton.length < 4) {
            throw new WebCustomException(I18nExceptionConstant.WEB_FORM_METADATA_ERROR_0015);
        }

        StringBuilder sourceProjectRelativePath = new StringBuilder();
        for (int i = 0; i <= 4; i++) {
            if (i != 0) {
                sourceProjectRelativePath.append("/");
            }
            sourceProjectRelativePath.append(soureMetadataSegmentPathColleciton[i]);
        }

        String sourceProjectAbsolutPath = MetadataUtility.getInstance().getAbsolutePath(sourceProjectRelativePath.toString());
        return getProjectInformation(sourceProjectAbsolutPath, sourceProjectName);
    }

    private static MetadataProject getProjectInformation(String projectAbsolutePath, String projectName) {
        String projectFileFullPath = Paths.get(projectAbsolutePath).resolve(projectName + "." + ReplicationConstant.METADATA_PROJECT_FILE_SUFFIX).toString();
        String projectFileContent = FileUtility.readAsString(projectFileFullPath);

        return SerializeUtility.getInstance().deserialize(projectFileContent, MetadataProject.class);
    }

    /**
     * 基于元数据获取元数据所在工程
     * 变化点，抽离出来，后续优化
     *
     * @param metadata 待查询元数据
     * @return 工程名
     */
    public static String getProjectName(GspMetadata metadata) {
        if (metadata == null || StringUtility.isNullOrEmpty(metadata.getRelativePath())) {
            return null;
        }
        // MetadataUtility.getNewInstance().getMetadataProject(metadata.getRelativePath()).getName()

        String[] metadataSegmentPathCollection = metadata.getRelativePath().replace("\\", "/").split(Pattern.quote("/"), -1);

        if (metadataSegmentPathCollection == null || metadataSegmentPathCollection.length < 4) {
            return null;
        }
        return metadataSegmentPathCollection[3];
    }
}
